#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "cJSON.h"
#include "common.h"
#include "user.h"
#include "client.h"

// 日志函数声明（需要从外部引入）
extern void logDebug(const char *format, ...);
extern void logInfo(const char *format, ...);
extern void logError(const char *format, ...);
extern void logFatal(const char *format, ...);

/**
 * 发送通用用户操作请求并获取响应
 * 
 * @param context 客户端上下文
 * @param dataType 数据类型
 * @param root JSON对象，包含请求数据
 * @param responseBuffer 用于存储响应的缓冲区
 * @param responseType 用于存储响应类型的指针
 * @return 成功返回0，失败返回-1
 */
static int sendUserRequest(ClientContext *context, unsigned char dataType, cJSON *root, 
                          char *responseBuffer, unsigned char *responseType) {
    char *jsonStr = cJSON_PrintUnformatted(root);
    int ret = sendPacket(context->sockfd, dataType, jsonStr);
    
    free(jsonStr);
    
    if (ret < 0) {
        logError("Failed to send user request");
        return -1;
    }
    
    // 等待响应
    if (waitForResponse(responseBuffer, MAX_BUFFER_SIZE, responseType) < 0) {
        logError("Failed to get response");
        return -1;
    }
    
    return 0;
}

// 用户登录
int userLogin(ClientContext *context, const char *username, const char *password) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "username", username);
    cJSON_AddStringToObject(root, "password", password);
    
    char responseBuffer[MAX_BUFFER_SIZE];
    unsigned char responseType;
    int ret = sendUserRequest(context, DATA_TYPE_USER_LOGIN, root, responseBuffer, &responseType);
    
    cJSON_Delete(root);
    
    if (ret < 0) {
        return -1;
    }
    
    cJSON *response = cJSON_Parse(responseBuffer);
    if (response) {
        if (responseType == DATA_TYPE_ACK) {
            cJSON *role = cJSON_GetObjectItem(response, "role");
            if (role) {
                strncpy(context->user.username, username, sizeof(context->user.username) - 1);
                strncpy(context->user.password, password, sizeof(context->user.password) - 1);
                strncpy(context->user.role, role->valuestring, sizeof(context->user.role) - 1);
                context->loggedIn = 1;
                logInfo("Login successful, user role: %s", role->valuestring);
                cJSON_Delete(response);
                return 0;
            }
        }
        cJSON_Delete(response);
    }
    
    logError("Login failed");
    return -1;
}

// 用户注册
int userRegister(ClientContext *context, const char *username, const char *password, const char *role) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "username", username);
    cJSON_AddStringToObject(root, "password", password);
    cJSON_AddStringToObject(root, "role", role);
    
    char responseBuffer[MAX_BUFFER_SIZE];
    unsigned char responseType;
    int ret = sendUserRequest(context, DATA_TYPE_USER_REGISTER, root, responseBuffer, &responseType);
    
    cJSON_Delete(root);
    
    if (ret < 0) {
        return -1;
    }
    
    if (responseType == DATA_TYPE_ACK) {
        logInfo("Register successful");
        return 0;
    }
    
    logError("Register failed");
    return -1;
}

// 修改密码
int userChangePassword(ClientContext *context, const char *oldPassword, const char *newPassword) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "username", context->user.username);
    cJSON_AddStringToObject(root, "oldPassword", oldPassword);
    cJSON_AddStringToObject(root, "newPassword", newPassword);
    
    char responseBuffer[MAX_BUFFER_SIZE];
    unsigned char responseType;
    int ret = sendUserRequest(context, DATA_TYPE_USER_CHANGE_PASSWORD, root, responseBuffer, &responseType);
    
    cJSON_Delete(root);
    
    if (ret < 0) {
        return -1;
    }
    
    if (responseType == DATA_TYPE_ACK) {
        strncpy(context->user.password, newPassword, sizeof(context->user.password) - 1);
        logInfo("Change password successful");
        return 0;
    }
    
    logError("Change password failed");
    return -1;
}

// 删除用户
int userDelete(ClientContext *context, const char *username) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "username", username);
    cJSON_AddStringToObject(root, "operator", context->user.username);
    
    char responseBuffer[MAX_BUFFER_SIZE];
    unsigned char responseType;
    int ret = sendUserRequest(context, DATA_TYPE_USER_DELETE, root, responseBuffer, &responseType);
    
    cJSON_Delete(root);
    
    if (ret < 0) {
        return -1;
    }
    
    if (responseType == DATA_TYPE_ACK) {
        logInfo("Delete user successful");
        return 0;
    }
    
    logError("Delete user failed");
    return -1;
}

// 查询用户
int userQuery(ClientContext *context, const char *username) {
    cJSON *root = cJSON_CreateObject();
    if (username) {
        cJSON_AddStringToObject(root, "username", username);
    }
    cJSON_AddStringToObject(root, "operator", context->user.username);
    
    char responseBuffer[MAX_BUFFER_SIZE];
    unsigned char responseType;
    int ret = sendUserRequest(context, DATA_TYPE_USER_QUERY, root, responseBuffer, &responseType);
    
    cJSON_Delete(root);
    
    if (ret < 0) {
        return -1;
    }
    
    // 打印用户信息
    printf("\n--- User Query Results ---");
    printf("%s\n", responseBuffer);
    printf("------------------------\n");
    
    return 0;
}

// 显示登录菜单
void showLoginMenu() {
    printf("\n==================================\n");
    printf("        光伏生产监测系统客户端        \n");
    printf("==================================\n");
    printf("1. 用户登录\n");
    printf("2. 用户注册（仅维护工程师可注册）\n");
    printf("0. 退出系统\n");
    printf("==================================\n");
    printf("请选择操作: ");
}

/**
 * 显示用户菜单（根据角色显示不同功能）
 * 
 * @param role 用户角色
 */
void showUserMenu(const char *role) {
    printf("\n==================================\n");
    printf("        光伏生产监测系统客户端        \n");
    printf("角色: %s\n", role);
    printf("==================================\n");
    
    // 用户管理部分 - 维护工程师特有
    if (strcmp(role, "maintenance_engineer") == 0) {
        printf("用户管理:\n");
    }
    
    // 所有用户都有的功能
    printf("1. 修改密码\n");
    
    // 维护工程师特有功能
    if (strcmp(role, "maintenance_engineer") == 0) {
        printf("2. 注册新用户\n");
        printf("3. 删除用户\n");
        printf("4. 查看所有用户\n");
    }
    
    // 数据管理部分
    printf("\n数据管理:\n");
    int baseOption = (strcmp(role, "maintenance_engineer") == 0) ? 5 : 2;
    printf("%d. 查询检测记录\n", baseOption);
    printf("%d. 删除检测记录\n", baseOption + 1);
    printf("%d. 申请抽查数据\n", baseOption + 2);
    printf("%d. 上传错误数据编号\n", baseOption + 3);
    printf("%d. 查询本地数据文件\n", baseOption + 4);
    
    printf("\n0. 退出登录\n");
    printf("==================================\n");
    printf("请选择操作: ");
}

/**
 * 处理密码修改功能
 * 
 * @param context 客户端上下文
 * @return 成功返回0，失败返回-1
 */
static int handlePasswordChange(ClientContext *context) {
    char oldPassword[50], newPassword[50], confirmPassword[50];
    printf("请输入旧密码: ");
    fgets(oldPassword, sizeof(oldPassword), stdin);
    oldPassword[strcspn(oldPassword, "\n")] = 0;
    
    printf("请输入新密码: ");
    fgets(newPassword, sizeof(newPassword), stdin);
    newPassword[strcspn(newPassword, "\n")] = 0;
    
    printf("请确认新密码: ");
    fgets(confirmPassword, sizeof(confirmPassword), stdin);
    confirmPassword[strcspn(confirmPassword, "\n")] = 0;
    
    if (strcmp(newPassword, confirmPassword) != 0) {
        printf("两次输入的新密码不一致！\n");
        return -1;
    } else if (userChangePassword(context, oldPassword, newPassword) == 0) {
        printf("密码修改成功！\n");
        return 0;
    } else {
        printf("密码修改失败，请重试！\n");
        return -1;
    }
}

/**
 * 处理数据查询功能
 * 
 * @param context 客户端上下文
 * @return 查询函数返回值
 */
static int handleDataQuery(ClientContext *context) {
    char batch[50], startDate[20], endDate[20], defectType[30];
    printf("请输入批次号(可选，直接回车跳过): ");
    fgets(batch, sizeof(batch), stdin);
    batch[strcspn(batch, "\n")] = 0;
    
    printf("请输入开始日期(可选，格式: YYYY-MM-DD): ");
    fgets(startDate, sizeof(startDate), stdin);
    startDate[strcspn(startDate, "\n")] = 0;
    
    printf("请输入结束日期(可选，格式: YYYY-MM-DD): ");
    fgets(endDate, sizeof(endDate), stdin);
    endDate[strcspn(endDate, "\n")] = 0;
    
    printf("请输入缺陷类型(可选): ");
    fgets(defectType, sizeof(defectType), stdin);
    defectType[strcspn(defectType, "\n")] = 0;
    
    return dataQuery(context, batch, startDate, endDate, defectType);
}

/**
 * 处理数据删除功能
 * 
 * @param context 客户端上下文
 * @return 成功返回0，失败返回-1
 */
static int handleDataDelete(ClientContext *context) {
    char batch[50], startDate[20], endDate[20];
    printf("请输入批次号(可选，直接回车跳过): ");
    fgets(batch, sizeof(batch), stdin);
    batch[strcspn(batch, "\n")] = 0;
    
    printf("请输入开始日期(可选，格式: YYYY-MM-DD): ");
    fgets(startDate, sizeof(startDate), stdin);
    startDate[strcspn(startDate, "\n")] = 0;
    
    printf("请输入结束日期(可选，格式: YYYY-MM-DD): ");
    fgets(endDate, sizeof(endDate), stdin);
    endDate[strcspn(endDate, "\n")] = 0;
    
    char confirm[10];
    printf("确定要删除满足条件的记录吗？(yes/no): ");
    fgets(confirm, sizeof(confirm), stdin);
    confirm[strcspn(confirm, "\n")] = 0;
    
    if (strcmp(confirm, "yes") == 0 || strcmp(confirm, "YES") == 0) {
        if (dataDelete(context, batch, startDate, endDate) == 0) {
            printf("数据删除成功！\n");
            return 0;
        } else {
            printf("数据删除失败！\n");
            return -1;
        }
    }
    return 0;
}

/**
 * 处理数据抽查申请功能
 * 
 * @param context 客户端上下文
 * @return 抽查函数返回值
 */
static int handleDataSampleRequest(ClientContext *context) {
    char batch[50], startDate[20], endDate[20];
    printf("请输入批次号(可选，直接回车跳过): ");
    fgets(batch, sizeof(batch), stdin);
    batch[strcspn(batch, "\n")] = 0;
    
    printf("请输入开始日期(可选，格式: YYYY-MM-DD): ");
    fgets(startDate, sizeof(startDate), stdin);
    startDate[strcspn(startDate, "\n")] = 0;
    
    printf("请输入结束日期(可选，格式: YYYY-MM-DD): ");
    fgets(endDate, sizeof(endDate), stdin);
    endDate[strcspn(endDate, "\n")] = 0;
    
    return dataSampleRequest(context, batch, startDate, endDate);
}

/**
 * 处理错误数据上报功能
 * 
 * @param context 客户端上下文
 * @return 成功返回0，失败返回-1
 */
static int handleErrorDataReport(ClientContext *context) {
    char waferId[50];
    printf("请输入错误电池片编号: ");
    fgets(waferId, sizeof(waferId), stdin);
    waferId[strcspn(waferId, "\n")] = 0;
    
    if (reportErrorData(context, waferId) == 0) {
        printf("错误数据编号上传成功！\n");
        return 0;
    } else {
        printf("错误数据编号上传失败！\n");
        return -1;
    }
}

/**
 * 处理用户操作（根据角色分发）
 * 
 * @param context 客户端上下文
 * @param choice 用户选择
 * @return 成功返回0，失败返回-1
 */
int handleUserOperation(ClientContext *context, int choice) {
    // 所有用户共用的功能
    if (choice == 0) {
        return 0; // 退出登录
    }
    
    if (choice == 1) {
        return handlePasswordChange(context);
    }
    
    // 数据管理功能的基础选项
    int dataManagementBase = 2;
    if (strcmp(context->user.role, "maintenance_engineer") == 0) {
        // 维护工程师特有功能
        switch (choice) {
            case 2: {
                // 注册新用户
                char username[50], password[50], confirmPassword[50], role[20];
                printf("请输入用户名: ");
                fgets(username, sizeof(username), stdin);
                username[strcspn(username, "\n")] = 0;
                
                printf("请输入密码: ");
                fgets(password, sizeof(password), stdin);
                password[strcspn(password, "\n")] = 0;
                
                printf("请确认密码: ");
                fgets(confirmPassword, sizeof(confirmPassword), stdin);
                confirmPassword[strcspn(confirmPassword, "\n")] = 0;
                
                printf("请选择角色(production_engineer/maintenance_engineer): ");
                fgets(role, sizeof(role), stdin);
                role[strcspn(role, "\n")] = 0;
                
                if (strcmp(password, confirmPassword) != 0) {
                    printf("两次输入的密码不一致！\n");
                    return -1;
                } else if (userRegister(context, username, password, role) == 0) {
                    printf("用户注册成功！\n");
                    return 0;
                } else {
                    printf("用户注册失败，请重试！\n");
                    return -1;
                }
            }
            case 3: {
                // 删除用户
                char username[50];
                printf("请输入要删除的用户名: ");
                fgets(username, sizeof(username), stdin);
                username[strcspn(username, "\n")] = 0;
                
                char confirm[10];
                printf("确定要删除用户 %s 吗？(yes/no): ", username);
                fgets(confirm, sizeof(confirm), stdin);
                confirm[strcspn(confirm, "\n")] = 0;
                
                if (strcmp(confirm, "yes") == 0 || strcmp(confirm, "YES") == 0) {
                    if (userDelete(context, username) == 0) {
                        printf("用户删除成功！\n");
                        return 0;
                    } else {
                        printf("用户删除失败！\n");
                        return -1;
                    }
                }
                return 0;
            }
            case 4: {
                // 查看所有用户
                return userQuery(context, NULL);
            }
            // 维护工程师的数据管理功能从5开始
            dataManagementBase = 5;
            break;
        }
    }
    
    // 数据管理功能（所有用户通用，但选项号不同）
    if (choice == dataManagementBase) {
        return handleDataQuery(context);
    } else if (choice == dataManagementBase + 1) {
        return handleDataDelete(context);
    } else if (choice == dataManagementBase + 2) {
        return handleDataSampleRequest(context);
    } else if (choice == dataManagementBase + 3) {
        return handleErrorDataReport(context);
    } else if (choice == dataManagementBase + 4) {
        // 查询本地数据文件
        queryLocalData();
        return 0;
    }
    
    printf("无效的选择，请重试！\n");
    return -1;
}